package com.yzh.luckydraw.domain.rule.service.logic;

import com.yzh.luckydraw.common.Constants;
import com.yzh.luckydraw.domain.rule.model.req.DecisionMatterReq;
import com.yzh.luckydraw.domain.rule.model.vo.TreeNodeLineVO;

import java.util.List;

public abstract class BaseLogic implements LogicFilter {
    /**
     * 规则决策
     * @param matterValue        决策值（用户信息，用作决策，例如用户性别、年龄）
     * @param treeNodeLineVOList 决策节点，包含链路信息（上一个、下一个节点）、限定类型（大于小于等于······）、限定值（和matterValue比对）
     * @return                   返回下一个节点的Id，外部循环调用filter方法，直到找到叶子节点才结束。（叶子节点存储着活动Id）
     */
    @Override
    public Long filter(String matterValue, List<TreeNodeLineVO> treeNodeLineVOList) {
        for (TreeNodeLineVO treeNodeLineVO : treeNodeLineVOList) {
            if (decisionLogic(matterValue, treeNodeLineVO)) {
                return treeNodeLineVO.getNodeIdTo();
            }
        }
        return Constants.Global.TREE_NULL_NODE;
    }

    /**
     * 获取决策值，由子类实现，因为决策策略可能有很多，不使用if/else
     * @param decisionMatterReq 决策请求信息
     * @return                  返回决策值
     */
    @Override
    public abstract String matterValue(DecisionMatterReq decisionMatterReq);

    /**
     * 根据库表中的LimitType规则（大于小于等等）使用matterValue和库表的value对比
     * @param matterValue   最终我们要匹配的值
     * @param nodeLine      规则树链路VO对象
     * @return              是否通过规则
     */
    private boolean decisionLogic(String matterValue, TreeNodeLineVO nodeLine) {
        switch (nodeLine.getRuleLimitType()) {
            case Constants.RuleLimitType.EQUAL:
                return matterValue.equals(nodeLine.getRuleLimitValue());
            case Constants.RuleLimitType.GT:
                return Double.parseDouble(matterValue) > Double.parseDouble(nodeLine.getRuleLimitValue());
            case Constants.RuleLimitType.LT:
                return Double.parseDouble(matterValue) < Double.parseDouble(nodeLine.getRuleLimitValue());
            case Constants.RuleLimitType.GE:
                return Double.parseDouble(matterValue) >= Double.parseDouble(nodeLine.getRuleLimitValue());
            case Constants.RuleLimitType.LE:
                return Double.parseDouble(matterValue) <= Double.parseDouble(nodeLine.getRuleLimitValue());
            default:
                return false;
        }
    }
}
